from odoo import api, fields, models, _


class SbSaleChange(models.Model):
    _inherit = 'sb.sale.change'

    change_apply_id = fields.Many2one('sale.change.apply', string='Change Apply')
    order_type = fields.Selection(related="change_apply_id.order_type", string='Order Change')
    sale_order_id = fields.Many2one('sale.order', String='Sale Order')
    sale_order_ids = fields.Many2many('sale.order')
    sale_order_ids_count = fields.Integer(default=0)

    @api.onchange('change_apply_id')
    def onchange_partner_info(self):
        if self.change_apply_id:
            self.line_ids = None
            self.partner_id = self.change_apply_id.partner_id.id
            self.product_tmpl_id = self.change_apply_id.product_tmpl_id.id
            self.sale_order_id = self.change_apply_id.sale_order_id.id
            self.code = self.change_apply_id.sale_order_id.pn
            self.version = self.change_apply_id.sale_order_id.pn_rev
            line_vals = []
            for line in self.change_apply_id.line_ids:
                # if line.sale_order_id.status != 'active': continue
                line_vals.append((0, 0, {
                    'sale_order_id': line.sale_order_id.id,
                    'order_line': line.order_line.id,
                    'qty': line.order_line.product_uom_qty,
                    'split_line_ids': [(4, s.id) for s in line.split_line_ids]
                }))
            self.line_ids = line_vals

    def action_split(self):
        # 取消，暂停，完成，都不能产生欠单
        # 存在发货单且发货的已交货或者部分交货，都不能拆单
        # 拆单后存在交货单的自动产生交货单
        workflow_tmpl_id = self.env['sb.workflow.template'].search([('workflow_type', '=', 'sale')])[0]
        new_orders = {}
        sale_order_vals = []
        cache_vals = []
        for line in self.line_ids:
            num = int(line.sale_order_id.name[-1]) + 1
            new_orders[line.sale_order_id] = []
            sale_order_vals.append((4, line.sale_order_id.id))
            for s in line.split_line_ids[1:]:
                new_sale_id, num = self.create_sale_order(s, workflow_tmpl_id, num)
                # 1 生成审批单据
                new_sale_id.create_workflow()
                # 2 审批单自动通过
                self.auto_approve(new_sale_id)
                new_orders[line.sale_order_id].append(new_sale_id.name)
                sale_order_vals.append((4, new_sale_id.id))
                cache_vals.append({
                    'sale_order_id': new_sale_id.id,
                    'order_line_id': new_sale_id.order_line[0].id,
                    'target_qty': s.split_qty,
                    'note': '拆分'
                })
            # 修改数据存储表
            cache_vals.append({
                'sale_order_id': line.sale_order_id.id,
                'order_line_id': line.order_line.id,
                'origin_qty': line.order_line.product_uom_qty,
                'target_qty': line.remain_qty,
                'note': '拆分'
            })
            line.order_line.with_context(ecr_apply=True).product_uom_qty = line.split_line_ids[0].split_qty
            line.is_option = True
        self.is_option = True
        message_fmt = ''
        for origin, new_names in new_orders.items():
            self._unlock_order(origin)
            message_fmt += "{}-->{}".format(origin.name, ','.join(new_names))
        self.message_post(body=message_fmt)
        self.sale_order_ids = sale_order_vals
        self.sale_order_ids_count = len(sale_order_vals)
        self.create_cache(cache_vals)

    def create_cache(self, vals):
        self.env['sb.order.cache'].create(vals)

    def action_see_split_order(self):
        return {
            'name': _('Sale Order'),
            'type': 'ir.actions.act_window',
            'res_model': 'sale.order',
            'view_mode': 'tree,form',
            'target': 'current',
            'domain': [('id', 'in', self.sale_order_ids.ids)]}

    def create_sale_order(self, s, workflow_tmpl_id, num):
        order_line = s.order_line
        name = s.sale_order_id.name
        new_name = "{}-0{}".format(name[:-4], str(num).zfill(2))
        # 创建新的销售单
        new_sale_id = self.env['sale.order'].with_context(ecr_apply=True).sudo().create({
            'partner_id': s.sale_order_id.partner_id.id,
            'special_order_type': s.sale_order_id.special_order_type,
            'po': s.sale_order_id.po,
            'pn': s.sale_order_id.pn,
            'pn_rev': s.sale_order_id.pn_rev,
            'end_pn': s.sale_order_id.end_pn,
            'end_pn_rev': s.sale_order_id.end_pn_rev,
            'end_po': s.sale_order_id.end_po,
            'product_id': s.sale_order_id.product_id.id,
            'unit_price': s.sale_order_id.unit_price,
            'commitment_date': s.sale_order_id.commitment_date,
            'final_delivery_date': s.sale_order_id.commitment_date,
            # 'planned_receiving_date': s.c_planned_receiving_date,
            'user_id': s.sale_order_id.user_id.id,
            'name': new_name,
            'create_uid': self.env.uid,
            'opportunity_id': s.sale_order_id.opportunity_id.id,
            'order_type': s.sale_order_id.order_type,
            'origin_sale_order': s.sale_order_id.name,
            'sb_workflow_template_id': workflow_tmpl_id.id,
            'order_line': [(0, 0, {
                'product_template_id': order_line.product_template_id.id,
                'pn': order_line.pn,
                'pn_rev': order_line.pn_rev,
                'po_line': order_line.po_line,
                # 'end_pn': order_line.end_pn,
                # 'end_pn_rev': order_line.end_pn_rev,
                # 'end_po': order_line.end_po,
                'product_id': order_line.product_id.id,
                'product_uom_qty': s.split_qty,
                'price_unit': order_line.price_unit,
                'origin_price': order_line.origin_price,
                'product_uom': order_line.product_template_id.uom_id.id,
            })]
        })
        return new_sale_id, num + 1

    def auto_approve(self, new_sale_id):
        # 自动审批通过，绕开审核限制
        for item in new_sale_id.sb_workflow_item_ids:
            item.sb_workflow_id_state = 'approve'
            item.state = 'pass'
        new_sale_id.sb_workflow_id.state = 'approve'

    def _unlock_order(self, sale_order):
        # 解锁销售单、发货的、工单、报废、过数等
        mrp_prods = set()
        # 解锁销售单
        sale_order.is_lock = False
        order_lines = sale_order.order_line
        picking_ids = sale_order.picking_ids
        sale_order.option_mrp_production_ids.filtered(lambda x: x.is_lock).is_lock = False
        for line in order_lines:
            for mrp in line.s_mrp_production_ids:
                if not mrp_prods:
                    mrp_prods = mrp
                mrp_prods |= self._get_parent_mrp(mrp)
                mrp_prods |= self._get_child_mrp(mrp)
                picking_ids |= mrp.picking_ids

        # 解锁工单
        for mrp in mrp_prods:
            mrp.filtered(lambda x: x.state != 'done').is_lock = False
            # mrp.is_lock = True
        # 解锁picking(出库和生产)
        for picking in picking_ids:
            picking.filtered(lambda x: x.state != 'done').is_lock = False
            # picking.is_lock = True

    def _get_parent_mrp(self, mrp):
        parent_ids = mrp._get_sources()
        # 欠单
        mrp_backorders = mrp.procurement_group_id.mrp_production_ids
        return parent_ids | mrp_backorders | mrp

    def _get_child_mrp(self, mrp):
        child_ids = mrp._get_children()
        # 欠单
        mrp_backorders = mrp.procurement_group_id.mrp_production_ids
        return child_ids | mrp_backorders


class SbSaleChangeLine(models.Model):
    _inherit = 'sb.sale.change.line'

    @api.depends('split_line_ids')
    def _compute_remain_qty(self):
        for rec in self:
            remain_qty = rec.qty
            remain_qty -= sum([s.split_qty for s in rec.split_line_ids])
            rec.remain_qty = remain_qty

    split_line_ids = fields.One2many("sale.split.apply.line", 'change_line_id', string='Split Lines')
    remain_qty = fields.Float(string='Remaining Split Qty', compute="_compute_remain_qty")

    def action_close(self):
        self._check_mo()
        self.sale_order_id.with_context(disable_cancel_warning=True, ecr_apply=True).action_cancel()
        self.sale_order_id.status = 'closed'
        self.change_id.is_option = True
        self.is_option = True
        self.send_message_port('关闭单据{}，出库单已取消'.format(self.sale_order_id.name))
        self._unlock_order()
        return {
            'type': 'ir.actions.client',
            'tag': 'display_notification',
            'params': {
                'type': 'success',
                'title': _("Cancel Sale Order"),
                'message': "已关闭销售单，并取消发货单。",
                'next': {
                    'type': 'ir.actions.act_window_close'
                },
            }
        }
